import { FrameworkConfigurator } from '../extension/scripts/framework-config';
import { copyFile, EXTENSION_PATH, getFileMd5, getFrameworkConfig } from './utils';

const fs = require('fs');
const path = require('path');
const glob = require('glob');
const gulp = require('gulp');
const ts = require('gulp-typescript');
const sourcemaps = require('gulp-sourcemaps');
const rename = require('gulp-rename');
const uglify = require('gulp-uglify');
const concat = require('gulp-concat');
const clean = require('gulp-clean');
const jsobfuscator = require('gulp-javascript-obfuscator');
const debug = require('gulp-debug');
const notify = require('gulp-notify');
const merge = require('merge2');
const through = require('through2');
const yargs = require('yargs');

/**
 * 构建脚本资源
 */
function buildScriptAssets(cb: () => void) {
    console.log('buildScriptAssets');
    let argv = yargs.default('modules', '*').argv;
    let modules: string = argv.modules;

    // 搜集资源TS文件
    let assetsTsFiles = [];
    let tsFiles = glob.sync(path.join(EXTENSION_PATH, 'assets', 'scripts', '**/*.ts'));
    for (let f of tsFiles) {
        assetsTsFiles.push(f.substring(f.indexOf('assets')).replace(/\\/g, '/'));
    }
    let assetsTsFileSet = new Set(assetsTsFiles);

    // 收集配置TS文件
    let frameworkConfig = new FrameworkConfigurator(getFrameworkConfig());
    if (modules === '*') {
        frameworkConfig.keepAllModules();
    } else {
        for (let module of modules.split(',')) {
            module = module.trim();
            frameworkConfig.keepModule(module);
        }
    }
    let configTsFiles = frameworkConfig.collectSources();
    console.log(
        `keepModules : [${frameworkConfig
            .collectModules()
            .map((v) => v.name)
            .join(',')}]`
    );

    // 复制配置TS文件到项目
    for (let tsfile of configTsFiles) {
        let srcTsFile = path.join(EXTENSION_PATH, 'framework', tsfile);
        let destTsFile = path.join(EXTENSION_PATH, 'assets', 'scripts', tsfile);
        if (!fs.existsSync(destTsFile) || getFileMd5(srcTsFile) !== getFileMd5(destTsFile)) {
            copyFile(srcTsFile, destTsFile);
        }
        assetsTsFileSet.delete(`assets/scripts/${tsfile}`);
    }

    // 生成资源lcc.ts文件
    fs.writeFileSync(
        path.join(EXTENSION_PATH, 'assets', 'scripts', 'lcc.ts'),
        frameworkConfig.collectExports().join('\n')
    );
    assetsTsFileSet.delete('assets/scripts/lcc.ts');

    // 删除未知框架TS文件
    let assetsTsFileDeletes = [...assetsTsFileSet];
    for (let dfile of assetsTsFileDeletes) {
        fs.unlinkSync(path.join(EXTENSION_PATH, dfile));
    }

    cb();
}

/**
 * 构建脚本声明
 */
function buildScriptDeclaration(cb: () => void) {
    if (fs.existsSync(`${EXTENSION_PATH}/assets/scripts`)) {
        console.log('buildScriptDeclaration');
        let tsResult = gulp
            .src([`${EXTENSION_PATH}/assets/scripts/**/*.ts`, `${EXTENSION_PATH}/@types/**/*.ts`])
            .pipe(
                ts.createProject(`${EXTENSION_PATH}/framework/tsconfig.json`, {
                    declaration: true,
                    removeComments: true,
                    noEmit: false,
                    composite: false,
                    outFile: 'lcc-framework'
                })()
            )
            .on('error', (err: any) => {
                console.error(err.message);
            });
        return tsResult.dts.pipe(gulp.dest(`${EXTENSION_PATH}/build`));
    } else {
        console.error('assets/scripts not found!');
        cb();
    }
}

export const build = gulp.series(buildScriptAssets, buildScriptDeclaration);
